package com.junzhiit.nengji.app.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bainaeco.framework.util.DateUtil;
import com.junzhiit.nengji.app.service.NoticeService;
import com.junzhiit.nengji.app.web.exception.NoticeNotFoundException;
import com.junzhiit.nengji.app.web.util.ViewObjectUtil;
import com.junzhiit.nengji.app.web.vo.DataTablesParamVO;
import com.junzhiit.nengji.app.web.vo.NoticeAddVO;
import com.junzhiit.nengji.app.web.vo.NoticeEditVO;
import com.junzhiit.nengji.app.web.vo.NoticeReadVO;
import com.junzhiit.nengji.app.web.vo.NoticeVO;
import com.junzhiit.nengji.app.web.vo.ResultVO;
import com.junzhiit.nengji.app.web.vo.SystemUserSessionVO;
import com.junzhiit.nengji.bo.NoticeBO;
import com.junzhiit.nengji.dao.NoticeDAO;
import com.junzhiit.nengji.dao.NoticeReadDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.Notice;
import com.junzhiit.nengji.model.NoticeRead;
import com.junzhiit.nengji.model.enums.Is;
import com.junzhiit.nengji.model.enums.LoginType;
import com.junzhiit.nengji.model.enums.NoticeStatus;
import com.junzhiit.nengji.model.enums.NoticeType;

@Service
public class NoticeServiceImpl extends BaseServiceImpl implements NoticeService {

	@Autowired
	private NoticeDAO noticeDAO;
	
	@Autowired
	private NoticeReadDAO noticeReadDAO;

	@Autowired
	private SystemUserCacheDAO systemUserCacheDAO;

	@Override
	public Map<String, Object> findAll(String sessionId, DataTablesParamVO dtp) {
		String key = DIYKey.getSessionHashKey(sessionId);
		SystemUserSessionVO session = systemUserCacheDAO.getHash(key, SystemUserSessionVO.class);
		String shopId=null;
		if (LoginType.SHOP.toIntType()==session.getLoginType()) {
			shopId=session.getSystemId();
		}
		
		List<NoticeBO> list = noticeDAO.findAll(dtp.getStart(), dtp.getLength(), shopId);
		int totalCount = noticeDAO.getTotalCount(shopId);
		return ViewObjectUtil.dataTables(list, dtp.getDraw(), totalCount);
	}

	@Override
	public Map<String, Object> findAllNoticeNews(DataTablesParamVO dtp) {
		List<NoticeBO> list=noticeDAO.findAllNoticeNews(dtp.getStart(), dtp.getLength());
		int totalCount = noticeDAO.getNoticeNewsCount();
		return ViewObjectUtil.dataTables(list, dtp.getDraw(), totalCount);
	}
	
	@Override
	public ResultVO findById(String id) {
		ResultVO resultVO = new ResultVO();
		NoticeBO notice = noticeDAO.findById(id);
		if (notice == null) {
			throw new NoticeNotFoundException("该公告不存在！");
		}
		NoticeVO noticeVO = new NoticeVO();
		BeanUtils.copyProperties(notice, noticeVO);
		resultVO.setData(noticeVO);
		return resultVO;
	}

	@Override
	public ResultVO add(String sessionId, NoticeAddVO noticeAddVO) {
		Notice notice = new Notice();
		BeanUtils.copyProperties(noticeAddVO, notice);
		ResultVO resultVO = new ResultVO();
		
		String key = DIYKey.getSessionHashKey(sessionId);
		SystemUserSessionVO session = systemUserCacheDAO.getHash(key, SystemUserSessionVO.class);
		if (LoginType.SHOP.toIntType()==session.getLoginType()) {
			notice.setShopId(session.getSystemId());
			notice.setType(NoticeType.SHOP.toIntValue());
			notice.setIsShop(Is.YES.toIntValue());
		}else{
			notice.setType(NoticeType.BASE.toIntValue());
		}
		
		notice.setStatus(NoticeStatus.ACTIVE.toIntStatus());
		notice.setIssuer(session.getSystemUserId());
		Notice param = noticeDAO.insert(notice);
		
		NoticeVO noticeVO = new NoticeVO();
		BeanUtils.copyProperties(param, noticeVO);
		
		resultVO.setData(noticeVO);
		return resultVO;
	}

	@Override
	public ResultVO delete(String id) {
		ResultVO resultVO = new ResultVO();
		try {
			resultVO.setData(noticeDAO.updateToDelete(id));
		} catch (Exception e) {
			throw new NoticeNotFoundException("该公告不存在！");
		}
		return resultVO;
	}

	@Override
	public ResultVO edit(NoticeEditVO noticeEditVO) {
		ResultVO resultVO = new ResultVO();
		Notice notice = noticeDAO.query(noticeEditVO.getId());
		
		if (notice == null) {
			throw new NoticeNotFoundException("该公告不存在！");
		}
		
		BeanUtils.copyProperties(noticeEditVO, notice);
		notice.setUpdatedTime(new Date());
		
		resultVO.setData(noticeDAO.update(notice));
		return resultVO;
	}

	@Override
	public ResultVO toTop(String id,String sessionId) {
		ResultVO resultVO = new ResultVO();
		
		String key = DIYKey.getSessionHashKey(sessionId);
		SystemUserSessionVO session = systemUserCacheDAO.getHash(key, SystemUserSessionVO.class);
		String shopId=null;
		if (LoginType.SHOP.toIntType()==session.getLoginType()) {
			shopId=session.getSystemId();
		}
		
		Notice notice = noticeDAO.query(id);
		if (notice == null) {
			throw new NoticeNotFoundException("该公告不存在！");
		}
		notice.setSort(noticeDAO.getMaxSort(shopId) + 1);
		notice.setUpdatedTime(new Date());
		
		resultVO.setData(noticeDAO.update(notice));
		return resultVO;
	}

	@Override
	public ResultVO changeStatus(String id) {
		ResultVO resultVO = new ResultVO();
		Notice notice = noticeDAO.query(id);
		
		if (notice == null) {
			throw new NoticeNotFoundException("该公告不存在！");
		}
		if (notice.getStatus() == NoticeStatus.INACTIVE.toIntStatus()) {
			notice.setStatus(NoticeStatus.ACTIVE.toIntStatus());
		} else {
			notice.setStatus(NoticeStatus.INACTIVE.toIntStatus());
		}
		
		notice.setUpdatedTime(new Date());
		resultVO.setData(noticeDAO.update(notice));
		return resultVO;
	}

	@Override
	public ResultVO makeFailure(String id) {
		ResultVO result=new ResultVO();
		Notice notice = noticeDAO.query(id);
		if (notice == null) {
			throw new NoticeNotFoundException("该公告不存在！");
		}
		notice.setStatus(NoticeStatus.FAILURE.toIntStatus());
		notice.setUpdatedTime(new Date());
		result.setData(noticeDAO.update(notice));
		return result;
	}

	@Override
	public ResultVO makeFailure() {
		ResultVO result=new ResultVO();
		List<Notice> list=noticeDAO.getFailureNotice(DateUtil.addDays(new Date(), -1));
		
		List<Notice> noticeList=new ArrayList<Notice>();
		for (Notice notice : list) {
			Notice param=new Notice();
			param.setId(notice.getId());
			param.setStatus(NoticeStatus.FAILURE.toIntStatus());
			param.setUpdatedTime(new Date());
			noticeList.add(param);
		}
		
		noticeDAO.batchUpdate(noticeList);
		return result;
	}

	@Override
	public Map<String, Object> findAllUnread(String sessionId, DataTablesParamVO dtp) {
		String key = DIYKey.getSessionHashKey(sessionId);
		SystemUserSessionVO session = systemUserCacheDAO.getHash(key, SystemUserSessionVO.class);
		//判断是否是商家
		String shopId=null;
		if (LoginType.SHOP.toIntType()==session.getLoginType()) {
			shopId=session.getSystemId();
		}
		//取得NoticeRead对象，如果没有就是第一次请求，按照当前时间创建一个记录返回空结果暂无可提示消息
		NoticeRead noticeRead = noticeReadDAO.queryByUserId(session.getSystemUserId());
		if(noticeRead!=null){
			List<NoticeBO> list = noticeDAO.findAllUnread(dtp.getStart(), dtp.getLength(), shopId,noticeRead);
			int totalCount =  noticeDAO.getUnreadTotalCount(shopId,noticeRead);
			return ViewObjectUtil.dataTables(list, dtp.getDraw(), totalCount);
		}else{
			noticeRead = new NoticeRead();
			noticeRead.setUserId(session.getSystemUserId());
			noticeRead.setPastRecord(new Date());
			noticeRead.setCurrentRecord(new Date());
			noticeReadDAO.insert(noticeRead);
			return null;
		}
	}

	@Override
	public ResultVO confirmNotice(NoticeReadVO read) {
		ResultVO result=new ResultVO();
		String key = DIYKey.getSessionHashKey(read.getSessionId());
		SystemUserSessionVO session = systemUserCacheDAO.getHash(key, SystemUserSessionVO.class);
		NoticeRead noticeRead = noticeReadDAO.queryByUserId(session.getSystemUserId());
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		if(noticeRead !=null){
			//判断是否是商家
			String shopId=null;
			if (LoginType.SHOP.toIntType()==session.getLoginType()) {
				shopId=session.getSystemId();
			}
			/* 将读取位置存储
			 * 判断上次执行位置-本次点击位置之间是否还存在未读消息
			 * 存在未读消息将拼接FinishReading字段，移动CurrentRecord指针
			 * 不存在将替换掉位置之间的FinishReading或者清空该字段，移动CurrentRecord、PastRecord指针
			 * */
			noticeRead.setCurrentRecord(read.getCurrentRecord());
			int totalCount =  noticeDAO.getUnreadTotalCountSubrange(shopId,noticeRead);
			//在区间内还存在未读的消息
			if(totalCount>=1){
				//拼接FinishReading
				String ret = sdf.format(read.getCurrentRecord());
				if(null != noticeRead.getFinishReading() && !"".equals(noticeRead.getFinishReading())){
					noticeRead.setFinishReading(noticeRead.getFinishReading()+','+ret);
				}else{
					noticeRead.setFinishReading(ret);
				}
				//移动指针
				noticeRead.setCurrentRecord(read.getCurrentRecord());
				//更换消息ID
				noticeRead.setNoticeId(read.getNoticeId());
			}else{
				//拼接FinishReading
				if(null != noticeRead.getFinishReading() && !"".equals(noticeRead.getFinishReading())){
					String ret = sdf.format(read.getCurrentRecord());
					String src[] = noticeRead.getFinishReading().split(",");
					String surplus = "";
					for(String s:src){
						if(ret.compareToIgnoreCase(s)<0){
							if(surplus == ""){
								surplus += s;
							}else{
								surplus += s+",";
							}
						}
					}
					noticeRead.setFinishReading(surplus);
				}else{
					noticeRead.setFinishReading("");
				}
				//移动指针
				noticeRead.setCurrentRecord(read.getCurrentRecord());
				noticeRead.setPastRecord(read.getCurrentRecord());
				//更换消息ID
				noticeRead.setNoticeId(read.getNoticeId());
			}
			boolean boo = noticeReadDAO.update(noticeRead);
			result.setData(boo);
		}else{
			result.setData("false");
		}
		return result;
	}

	@Override
	public ResultVO confirmAllNotice(String sessionId) {
		ResultVO result=new ResultVO();
		String key = DIYKey.getSessionHashKey(sessionId);
		SystemUserSessionVO session = systemUserCacheDAO.getHash(key, SystemUserSessionVO.class);
		NoticeRead noticeRead = noticeReadDAO.queryByUserId(session.getSystemUserId());
		Date date = new Date();
		//移动指针
		noticeRead.setPastRecord(date);
		noticeRead.setCurrentRecord(date);
		//更换消息ID
		noticeRead.setNoticeId("");
		noticeRead.setFinishReading("");
		result.setData(noticeReadDAO.update(noticeRead));
		return result;
	}

}
